package cn.com.nes.site.service.crm.flow.impl;

import cn.com.nes.common.exception.IllegalBusinessException;
import cn.com.nes.common.exception.MissBusinessParameterException;
import cn.com.nes.common.util.CopyUtils;
import cn.com.nes.mybatis.agent.ope.entity.CrmFlowTableRelationship;
import cn.com.nes.mybatis.agent.ope.mapper.CrmFlowTableRelationshipMapper;
import cn.com.nes.site.entity.bo.crm.BatchSaveCrmFlowDataBO;
import cn.com.nes.site.entity.bo.crm.CrmFlowTableRelationshipBO;
import cn.com.nes.site.entity.bo.crm.sale.BatchDeleteCrmFlowDataBO;
import cn.com.nes.site.entity.vo.workOrder.GetWorkOrderInstallPageVO;
import cn.com.nes.site.service.crm.flow.CrmFlowTableRelationshipService;
import cn.com.nes.site.service.crm.flow.dto.CrmFlowTableRelationshipDTO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * crm流程相关表关系Service
 *
 * @Author: ShenWei
 * @Date: 2024/08/23/15:27
 */
@Slf4j
@Service
public class CrmFlowTableRelationshipServiceImpl extends ServiceImpl<CrmFlowTableRelationshipMapper, CrmFlowTableRelationship> implements CrmFlowTableRelationshipService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchInsertCrmFlowData(BatchSaveCrmFlowDataBO bo) throws Exception {
        if (CollectionUtil.isEmpty(bo.getDataList())) {
            throw new IllegalBusinessException("CrmFlowTableRelationshipBoList must not empty");
        }
        for (CrmFlowTableRelationshipBO flowData : bo.getDataList()) {
            validateParamNotBlank(flowData);
            flowData.setId(null);
        }
        // 转换为实体List
        List<CrmFlowTableRelationship> crmFlowTableRelationships = CopyUtils.copyList(bo.getDataList(), CrmFlowTableRelationship.class);
        // 设置初始参数
        for (CrmFlowTableRelationship crmFlowTableRelationship : crmFlowTableRelationships) {
            crmFlowTableRelationship.setDeleted(false);
            crmFlowTableRelationship.setGmtCreate(bo.getOperateDate());
            crmFlowTableRelationship.setGmtCreateId(bo.getOperateUserId());
            crmFlowTableRelationship.setGmtModified(bo.getOperateDate());
            crmFlowTableRelationship.setGmtModifiedId(bo.getOperateUserId());
        }
        // 批量保存
        boolean success = this.saveBatch(crmFlowTableRelationships, crmFlowTableRelationships.size());
        if (!success) {
            throw new IllegalBusinessException("批量新增crm流程关系数据失败!");
        }
    }

    @Override
    @Transactional(rollbackFor =  Exception.class)
    public void updateCrmFlowData(CrmFlowTableRelationshipBO bo) throws Exception {
        if (ObjectUtil.isNull(bo.getId())) {
            throw new MissBusinessParameterException("id must not null");
        }
        validateParamNotBlank(bo);
        // 创建实体
        CrmFlowTableRelationship crmFlowTableRelationship = new CrmFlowTableRelationship();
        BeanUtils.copyProperties(bo, crmFlowTableRelationship);
        // 更新数据
        boolean success = this.updateById(crmFlowTableRelationship);
        if (!success) {
            throw new IllegalBusinessException("修改crm流程关系数据失败!");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteCrmFlowData(BatchDeleteCrmFlowDataBO bo) throws Exception {
        if (CollectionUtil.isEmpty(bo.getIdSet())) {
            throw new MissBusinessParameterException("idSet must not empty");
        }
        // 创建实体
        CrmFlowTableRelationship crmFlowTableRelationship = new CrmFlowTableRelationship();
        crmFlowTableRelationship.setDeleted(true);
        crmFlowTableRelationship.setGmtModifiedId(bo.getOperateUserId());
        crmFlowTableRelationship.setGmtModified(bo.getOperateDate());

        QueryWrapper<CrmFlowTableRelationship> wrapper = new QueryWrapper<>();
        wrapper.in("id", bo.getIdSet());

        Integer rows = this.baseMapper.update(crmFlowTableRelationship, wrapper);
        if (rows != bo.getIdSet().size()) {
            throw new IllegalBusinessException("批量删除crm流程关系数据失败!");
        }
    }

    @Override
    public List<CrmFlowTableRelationshipDTO> selectCrmFlowDataList(CrmFlowTableRelationshipBO bo) throws Exception {
        QueryWrapper<CrmFlowTableRelationship> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", false);
        if (ObjectUtil.isNotNull(bo.getId())) {
            wrapper.eq("id", bo.getId());
        }
        if (StrUtil.isNotBlank(bo.getOpportunityUuid())) {
            wrapper.eq("opportunity_uuid", bo.getOpportunityUuid());
        }
        if (ObjectUtil.isNotNull(bo.getSaleOrderId())) {
            wrapper.eq("sale_order_id", bo.getSaleOrderId());
        }
        if (ObjectUtil.isNotNull(bo.getSalePriceMasterId())) {
            wrapper.eq("sale_price_master_id", bo.getSalePriceMasterId());
        }
        if (ObjectUtil.isNotNull(bo.getWorkOrderId())) {
            wrapper.eq("work_order_id", bo.getWorkOrderId());
        }
        return CopyUtils.copyList(this.list(wrapper), CrmFlowTableRelationshipDTO.class);
    }

    @Override
    public Map<Long, Long> getWorkOrderProjectIdMap(Set<Long> workOrderIdSet) {
        if (CollectionUtil.isEmpty(workOrderIdSet)) {
            throw new IllegalBusinessException("workOrderIdSet must not empty");
        }
        // 查询工单id对应的最新的商机id,查询商机id对应的最新的项目id
        List<Map<String, Long>> workOrderProjectIdMapList = this.baseMapper.getWorkOrderProjectIdMap(workOrderIdSet);
        if (CollectionUtil.isEmpty(workOrderProjectIdMapList)) {
            return new HashMap<>();
        }
        Map<Long, Long> workOrderProjectIdMap = new HashMap<>();
        for (Map<String, Long> map : workOrderProjectIdMapList) {
            workOrderProjectIdMap.put(map.get("workOrderId"), map.get("projectId"));
        }

        return workOrderProjectIdMap;
    }

    @Override
    public Set<Long> getWorkOrderIdSetByProjectId(Long projectId) {
        if (ObjectUtil.isNull(projectId)) {
            throw new IllegalBusinessException("projectId must not null");
        }
        // 根据项目id查询工单id集合
        return this.baseMapper.getWorkOrderIdSetByProjectId(projectId);
    }

    @Override
    public Set<Long> getWorkOrderIdSetByProjectIdSet(Set<Long> projectIdSet) {
        if (CollectionUtil.isEmpty(projectIdSet)) {
            throw new IllegalBusinessException("projectIdSet must not empty");
        }
        Set<Long> workOrderIdSet = new HashSet<>();
        for (Long projectId : projectIdSet) {
           if (ObjectUtil.isNull(projectId)) {
               continue;
           }
            workOrderIdSet.addAll(this.getWorkOrderIdSetByProjectId(projectId));
        }
        return workOrderIdSet;
    }

    @Override
    public List<Long> getProjectIdList(List<Long> workOrderIdList) {
        if (CollectionUtil.isEmpty(workOrderIdList)) {
            throw new IllegalBusinessException("workOrderIdList must not empty");
        }
        Map<Long, Long> workOrderProjectIdMap = this.getWorkOrderProjectIdMap(new HashSet<>(workOrderIdList));
        if (CollectionUtil.isEmpty(workOrderProjectIdMap)) {
            return Collections.emptyList();
        }

        Set<Long> projectIdSet = new HashSet<>();
        for (Long workOrderId : workOrderProjectIdMap.keySet()) {
            projectIdSet.add(workOrderProjectIdMap.get(workOrderId));
        }

        return new ArrayList<>(projectIdSet);
    }

    @Override
    public Long getProjectId(Long workOrderId) {
        if (ObjectUtil.isNull(workOrderId)) {
            throw new IllegalBusinessException("workOrderId must not null");
        }
        Map<Long, Long> workOrderProjectIdMap = this.getWorkOrderProjectIdMap(Collections.singleton(workOrderId));
        return workOrderProjectIdMap.get(workOrderId);
    }

    @Override
    public Map<String, List<Long>> getSaleOrderIdMap(List<Long> workOrderIdList) {
        if (CollectionUtil.isEmpty(workOrderIdList)) {
            throw new MissBusinessParameterException("workOrderIdList must not empty");
        }

        QueryWrapper<CrmFlowTableRelationship> wrapper = new QueryWrapper<>();
        wrapper.in("work_order_id", workOrderIdList);
        wrapper.eq("deleted", false);
        List<CrmFlowTableRelationship> crmFlowTableRelationships = this.baseMapper.selectList(wrapper);

        Map<String, List<Long>> map = new HashMap<>();
        map.put("priceMasterIdList", crmFlowTableRelationships.stream().map(CrmFlowTableRelationship::getSalePriceMasterId).collect(Collectors.toList()));
        map.put("saleOrderIdList", crmFlowTableRelationships.stream().map(CrmFlowTableRelationship::getSaleOrderId).collect(Collectors.toList()));
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteCrmFlowData(List<Long> workOrderIdList, Date operateDate, Long operateUserId) throws Exception {
        if (CollectionUtil.isEmpty(workOrderIdList)) {
            throw new MissBusinessParameterException("workOrderIdList must not empty");
        }

        QueryWrapper<CrmFlowTableRelationship> wrapper = new QueryWrapper<>();
        wrapper.in("work_order_id", workOrderIdList);
        wrapper.eq("deleted", false);
        List<CrmFlowTableRelationship> crmFlowTableRelationships = this.baseMapper.selectList(wrapper);

        Set<Long> idSet = crmFlowTableRelationships.stream().map(CrmFlowTableRelationship::getId).collect(Collectors.toSet());
        if (CollectionUtil.isEmpty(idSet)) {
            return;
        }

        BatchDeleteCrmFlowDataBO batchDeleteCrmFlowDataBO = new BatchDeleteCrmFlowDataBO();
        batchDeleteCrmFlowDataBO.setIdSet(idSet);
        batchDeleteCrmFlowDataBO.setOperateDate(operateDate);
        batchDeleteCrmFlowDataBO.setOperateUserId(operateUserId);
        this.batchDeleteCrmFlowData(batchDeleteCrmFlowDataBO);
    }

    @Override
    public Set<Long> getWorkOrderIdSet(GetWorkOrderInstallPageVO vo) {
        if (ObjectUtil.isNull(vo)) {
            throw new IllegalBusinessException("vo must not null");
        }
        return this.baseMapper.getWorkOrderIdSet(vo.getProjectId(), vo.getProjectName(), vo.getProjectType(), vo.getProjectStatus(), vo.getOperateUserCompanyId());
    }


    // 校验入参非空
    void validateParamNotBlank(CrmFlowTableRelationshipBO bo) {
        if (ObjectUtil.isNull(bo.getOpportunityUuid())) {
            throw new MissBusinessParameterException("opportunityUuid must not null");
        }
        if (ObjectUtil.isNull(bo.getSaleOrderId())) {
            throw new MissBusinessParameterException("saleOrderId must not null");
        }
        if (ObjectUtil.isNull(bo.getSalePriceMasterId())) {
            throw new MissBusinessParameterException("salePriceMasterId must not null");
        }
        if (ObjectUtil.isNull(bo.getWorkOrderId())) {
            throw new MissBusinessParameterException("workOrderId must not null");
        }
    }
}
